﻿using System;
using UnityEngine;

namespace WentStateMachine
{
    [Serializable]
    public class State : ScriptableObject, IStateInfo
    {
        public StateBehaviour[] behaviours;

        private string _name;
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                name = value;
                _nameHash = Helper.ScriptingStringToCRC32(value);
                _name = value;
            }
        }

        [SerializeField] private int _nameHash;
        public int nameHash
        {
            get
            {
                return _nameHash;
            }
            set
            {
                _nameHash = value;
            }
        }

        [SerializeField] private Transition[] transitions;
        public Transition[] Transitions {
            get
            {
                return transitions;
            }

            set
            {
                transitions = value;
            }
        }

        public void Init(StateMachine owner)
        {
            Owner = owner;
            if(behaviours != null)
            {
                for(int i = 0; i < behaviours.Length; i++)
                {
                    behaviours[i] = ScriptableObject.Instantiate(behaviours[i]);
                }
            }
        }

        public bool IsHash(int hash)
        {
            return nameHash == hash;
        }

        public bool IsName(string name)
        {
            return Helper.ScriptingStringToCRC32(name) == nameHash;
        }

        public StateMachine Owner
        {
            get;
            private set;
        }

        public void Enter(StateMachineController controller, int layerIndex)
        {
            if (behaviours == null)
                return;
            foreach (var behaviour in behaviours)
            {
                behaviour.OnWentStateEnter(controller, this, layerIndex);
            }
        }

        public void OnUpdate(StateMachineController controller, int layerIndex)
        {
            if (behaviours == null)
                return;
            foreach (var behaviour in behaviours)
            {
                behaviour.OnWentStateUpdate(controller, this, layerIndex);
            }
        }

        public void Exit(StateMachineController controller, int layerIndex)
        {
            if (behaviours == null)
                return;
            foreach (var behaviour in behaviours)
            {
                behaviour.OnWentStateExit(controller, this, layerIndex);
            }
        }

        public override bool Equals(object obj)
        {
            State other = obj as State;
            if (other == null)
                return false;
            return other.nameHash == nameHash;
        }

        public override int GetHashCode()
        {
            return 21 + nameHash.GetHashCode();
        }
    }
}
